﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;
using Bids.Core.Common.Net;
using Bids.Core.Common.Security;
using Bids.Core.Common.Data;

namespace Bids.Core.Common.Pay
{
    public class Epaylinks 
    {
        //接口地址
        string url = WebConfigurationManager.AppSettings["Epaylinks_PayApiURL"];
        //string url = "http://219.136.207.190/paycenter/TestPayCenter/v3.0/payCreate.jsp"; //测试环境
        
        //商户编号
        //string partner = "130";
        string partner = WebConfigurationManager.AppSettings["Epaylinks_Partner"];
        //商户密钥
        static string key = WebConfigurationManager.AppSettings["Epaylinks_Key"];
        //static string key = "857e6g8y51b5k365f7v954s50u24h14w";//测试环境
        //货币代码
        string currency_Type = "RMB";
        //同步通知地址
        string return_url = WebConfigurationManager.AppSettings["Epaylinks_ReturnURL"];
        //异步通知地址
        string notify_url = WebConfigurationManager.AppSettings["Epaylinks_NotifyURL"];
        //版本 默认是3.0
        string version = "3.0";
        //签名类型
        string sign_type = "SHA256";


        //商户订单号
        string out_trade_no = "";
        //订单金额
        decimal total_fee = 0m; 
        //订单生成的机器IP，指用户浏览器端IP，不是商户服务器IP
        string order_create_ip = "";
        //银行直连编码
        string pay_id = "";
        //订单备注（需要进行BASE64编码）
        string base64_memo = "";


        //前置银行列表
        public List<EpayBank> BankList { get; private set; }

        public Epaylinks(string outTradeNo,decimal totalFee,string payId,string memo)
        {
            this.out_trade_no = outTradeNo;
            this.total_fee = totalFee;
            this.order_create_ip = RequestHelper.GetIP();
            this.base64_memo = memo.ToBase64();
            this.pay_id = payId;
            #region 初始化银行列表
            this.BankList = new List<EpayBank>();
            this.BankList.Add(new EpayBank {
                BankCode = "gonghang",
                BankLogo = "中国工商银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "zhonghang",
                BankLogo = "中国银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "jiaohang",
                BankLogo = "中国交通银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "zhaohang",
                BankLogo = "招商银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "guangda",
                BankLogo = "中国光大银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "nonghang",
                BankLogo = "中国农业银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "nonghangb2b",
                BankLogo = "农行企业网银",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "zhongxin",
                BankLogo = "中信银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "jianhang",
                BankLogo = "建设银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "jianhangb2b",
                BankLogo = "建行企业网银",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "gonghangb2b",
                BankLogo = "工行企业网银",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "zhaohangb2b",
                BankLogo = "招行企业网银",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "shenfa",
                BankLogo = "深圳发展银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "minsheng",
                BankLogo = "民生银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "shangye",
                BankLogo = "商业银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "guangfa",
                BankLogo = "广东发展银",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "xingye",
                BankLogo = "兴业银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "pufa",
                BankLogo = "上海浦东发展银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "pingan",
                BankLogo = "平安银行",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "alipay",
                BankLogo = "支付宝",
                BankName = "",
            });
            this.BankList.Add(new EpayBank
            {
                BankCode = "tenpay",
                BankLogo = "财付通",
                BankName = "",
            });
            #endregion
        }

        /// <summary>
        /// 支付地址
        /// </summary>
        public string PayUrl
        {
            get
            {
                string payUrl = string.Format("{0}?base64_memo={1}&currency_type={2}&notify_url={3}&order_create_ip={4}&out_trade_no={5}&partner={6}&pay_id={7}&return_url={8}&sign={9}&sign_type={10}&total_fee={11}&version={12}"
                     , this.url, HttpContext.Current.Server.UrlEncode(this.base64_memo), this.currency_Type, this.notify_url, this.order_create_ip, this.out_trade_no, this.partner, this.pay_id, this.return_url, this.GetSign(), this.sign_type, this.total_fee, this.version);

                return payUrl;
            }
        }

        private string GetSign()
        {
            var str = string.Format("base64_memo={0}&currency_type={1}&notify_url={2}&order_create_ip={3}&out_trade_no={4}&partner={5}" + (string.IsNullOrEmpty(pay_id) ? "" : "&pay_id={6}") + "&return_url={7}&sign_type={8}&total_fee={9}&version={10}&key={11}"
                 , this.base64_memo, this.currency_Type,  this.notify_url, this.order_create_ip, this.out_trade_no, this.partner, this.pay_id, this.return_url,this.sign_type,this.total_fee,this.version,key);
           
           return str.ToSHA256(); 
        }
        /// <summary>
        /// 验证同步、异步通知签名
        /// </summary>
        /// <returns></returns>
        public static bool ValidateSign()
        {
            var queryString = HttpContext.Current.Request.QueryString;
            var str = string.Format("amount={0}&base64_memo={1}&out_trade_no={2}&partner={3}&pay_no={4}&pay_result={5}&sett_date={6}&sign_type={7}&version={8}&key={9}"
                ,queryString["amount"],queryString["base64_memo"],queryString["out_trade_no"],queryString["partner"],queryString["pay_no"],queryString["pay_result"],queryString["sett_date"],queryString["sign_type"],queryString["version"],key);
           if (string.Compare(queryString["sign"],str.ToSHA256(),true) == 0)
                return true;
            return false;
        }
    }
    
    public class EpayBank
    {
        public string BankName { get; set; }
        public string BankCode { get; set; }
        public string BankLogo { get; set; }
    }
}